/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package graphviewer;

import service.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;

/**
 *
 * @author Sabitov Artem
 * @since 09.07.2013
 */
public class Node extends JPanel {
	private int ID;
	private double cX;
	private double cY;
	private double cOldX;
	private double cOldY;
	private double offsetX;
	private double offsetY;
	private double nodeRadius = 24; // радиус ноды
	private static int nodeCount = 0; // количество нодов
	private boolean active;
	private ArrayList<Edge> edges;
	
	public Node(double x, double y) {
		cX = x;
		cY = y;
		nodeCount++;
		ID = nodeCount;
		edges = new ArrayList<>();
		setBounds((int) cX - 12, (int) cY - 12, 71, 25);
		setOpaque(Service.getStateDebugComponent());
		setBackground(Color.GREEN);
	}
	
	// отрисовка
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.fillOval(0, 0, (int) nodeRadius, (int) nodeRadius);
		if(Service.getServiceState()) {
			Font font = new Font("Arial", 0, 9);
			g2d.setFont(font);
			g2d.drawString("x:" + cX, 30, 10);
			g2d.drawString("y:" + cY, 30, 20);
			g2d.setColor(Color.RED);
			g2d.drawString("id:" + ID, 3, 16);
		}
		setBounds((int)(cX - nodeRadius/2), (int)(cY - nodeRadius/2), (int) (nodeRadius*3), (int) (nodeRadius*2));
		paintEdges();
	}
	
	public boolean isActive() {
		return active;
	}
	
	public void setActive(boolean state) {
		active = state;
	}
	
	public double getNodeRadius() {
		return nodeRadius;
	}
	public void setNodeRadius(double radius) {
		nodeRadius = radius;
		this.repaint();
	}
	
	public int getID() {
		return ID;
	}
	public static int getCountNodes() {
		return nodeCount;
	}
	
	// методы для работы с координатами
	public double getCoordX() {
		return cX;
	}
	public double getCoordY() {
		return cY;
	}
	public double getOldX() {
		return cOldX;
	}
	public double getOldY() {
		return cOldY;
	}
	
	public void setX(double x) {
		cX = x;
	}
	public void setY(double y) {
		cY = y;
	}
	public void setCoords(double x, double y) {
		cX = x;
		cY = y;
		repaint();
		//setBounds((int) cX - 12, (int) cY - 12, 71, 24);
		setBounds((int)(cX - nodeRadius/2), (int)(cY - nodeRadius/2), (int) (nodeRadius*3), (int) (nodeRadius*2));
	}
	// методы для работы с смещением
	public void performOffset() {
		if(offsetX != 0 && offsetY != 0) {
			cOldX = cX;
			cOldY = cY;
			cX += offsetX;
			cY += offsetY;
			repaint();
			setBounds((int) cX - 12, (int) cY - 12, 71, 24);
			resetOffset();
		}
	}
	public void setOffset(Offset offset) {
		offsetX += offset.offsetX;
		offsetY += offset.offsetY;
	}
	public void setOffset(double moveX, double moveY) {
		offsetX += moveX;
		offsetY += moveY;
	}
	public void setOffsetX(int moveX) {
		offsetX += moveX;
	}
	public void setOffsetY(int moveY) {
		offsetY += moveY;
	}
	public double getOffsetX() {
		return offsetX;
	}
	public boolean isNullOffset() {
		if(offsetX == 0 && offsetY == 0) {
			return true;
		} else return false;
	}
	public double getOffsetY() {
		return offsetY;
	}
	
	private void resetOffset() {
		offsetX = 0;
		offsetY = 0;
		// #remake
		for(int i = 0; i < edges.size(); i++) {
			edges.get(i).update();
		}
	}
	
	// методы для работы с ребрами
	// #remake
	public void setEdge(Node node) {
		Edge edge = new Edge(this, node);
		edges.add(edge);
		node.addReverseEdge(edge);
		update();
	}
	
	private void addReverseEdge(Edge edge) {
		edges.add(edge);
	}
	
	private void paintEdges() {
		if(!edges.isEmpty()) {
			for(int i = 0; i < edges.size(); i++) {
				Storage.getViewer().add(edges.get(i));
			}
		}
	}
	
	// #remake
	public boolean checkEdge(Node node) {
		if(edges.isEmpty()) { 
			return false;
		}
		for(int i = 0; i < edges.size(); i++) {
			if(edges.get(i).checkEdge(node)) return true;
		}
		return false;
	}
	
	public void update() {
		performOffset();
		repaint();
	}
}
